﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Snowflake.Entity;
using System.Data.Common;
using System.Data.SqlClient;

namespace Snowflake.Gateway
{
    internal class UpdateQuery<TEntity> : EntityQuery<TEntity> where TEntity : EntityObject<TEntity>, new()
    {
        private Dictionary<string, object> _ColumnsForUpdate;

        public UpdateQuery(IQueryable<TEntity> query, Dictionary<string, object> columnsForUpdate)
            : base(query)
        {
            this._ColumnsForUpdate = columnsForUpdate;
        }

        protected internal override string TranslateSQLQuery(string tableName, string commandText, DbParameterCollection parameters)
        {
            StringBuilder builderUpdateStatement = new StringBuilder();

            int count = 1;
            int columnsForUpdateCount = this._ColumnsForUpdate.Count;

            foreach (KeyValuePair<string, object> keyValuePair in this._ColumnsForUpdate)
            {
                string column = keyValuePair.Key;
                string paramColumnName = "@" + column.Replace(" ", String.Empty);
                object value = keyValuePair.Value;

                builderUpdateStatement.AppendFormat("[{0}]={1}", column, paramColumnName);

                if (count < columnsForUpdateCount)
                    builderUpdateStatement.Append(",");

                count++;

                SqlParameter sqlParameter = new SqlParameter(paramColumnName, value);
                parameters.Add(sqlParameter);
            }

            string columnsForUpdate = builderUpdateStatement.ToString();

            StringBuilder builderCommand = new StringBuilder();
            builderCommand.AppendLine("DECLARE update_cursor CURSOR FOR ");
            builderCommand.AppendLine(commandText + " ");
            builderCommand.AppendLine("OPEN update_cursor ");
            builderCommand.AppendLine("FETCH FROM update_cursor ");
            builderCommand.AppendLine("WHILE @@FETCH_STATUS = 0 ");
            builderCommand.AppendLine(" BEGIN ");
            builderCommand.AppendFormat("  UPDATE {0} SET {1} WHERE CURRENT OF update_cursor", tableName, columnsForUpdate);
            builderCommand.AppendLine(Environment.NewLine + "  FETCH NEXT FROM update_cursor ");
            builderCommand.AppendLine(" END ");
            builderCommand.AppendLine("CLOSE update_cursor ");
            builderCommand.AppendLine("DEALLOCATE update_cursor ");

            return builderCommand.ToString();
        }
    }
}
